package neu.soft.message;

import neu.soft.constant.OrderStatus;
import neu.soft.entity.GoodsTransferOrder;
import neu.soft.entity.InvoiceGoodInfo;
import neu.soft.entity.OperationPurchaseOrder;
import neu.soft.feign.DispatchFeignClient;
import neu.soft.feign.UserFeignClient;
import neu.soft.service.impl.*;
import neu.soft.vo.MsgBean;
import org.apache.rocketmq.common.message.MessageConst;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.MimeTypeUtils;

import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ReceiveService {
    @Autowired
    private EntryOrderServiceImpl entryOrderService;

    @Autowired
    private EIRelationServiceImpl eiRelationService;

    @Autowired
    private OutOrderServiceImpl outOrderService;

    @Autowired
    private DistributionOrderServiceImpl distributionOrderService;

    @Autowired
    private DIRelationServiceImpl diRelationService;

    @Autowired
    private InventoryServiceImpl inventoryService;

    @Autowired
    private DispatchFeignClient dispatchFeignClient;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private MessageSource source;

    public <T> boolean checkPurchase(T msg, Integer delay){
        Message<T> message = MessageBuilder.withPayload(msg)
                .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, delay)
                .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON)
                .build();
        System.out.println(message);
        return source.checkPurchase().send(message);
    }

    public <T> boolean checkPurchase1(T msg, Integer delay){
        Message<T> message = MessageBuilder.withPayload(msg)
                .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, delay)
                .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON)
                .build();
        System.out.println(message);
        return source.confirmOut1().send(message);
    }

    public <T> boolean confirmDistribute(T msg, Integer delay){
        Message<T> message = MessageBuilder.withPayload(msg)
                .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, delay)
                .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON)
                .build();
        System.out.println("fadsadsffdsafdsa");
        System.out.println(message);
        System.out.println("1324413232321");
        return source.confirmDistribute().send(message);
    }

    public <T> boolean confirmPurchaseIn(T msg, Integer delay){
        Message<T> message = MessageBuilder.withPayload(msg)
                .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, delay)
                .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON)
                .build();
        System.out.println(message);
        return source.confirmPurchaseIn().send(message);
    }

    @StreamListener("create-purchaseOrder")
    public void receivePurchaseOrder(@Payload MsgBean<OperationPurchaseOrder> receiveMsg){
        OperationPurchaseOrder purchaseOrder = receiveMsg.getData();
        entryOrderService.addPurchaseOrder(purchaseOrder);
        entryOrderService.batchInsertGoodInfo(purchaseOrder.getGoodInfoList());
    }

    // 在采购单填写完成后，填写中心库房入库单
    @StreamListener("create-entryOrder")
    public void createEntryOrder(@Payload MsgBean<List<InvoiceGoodInfo>> receiveMsg){
        String str = receiveMsg.getMsg();
        List<InvoiceGoodInfo> invoiceGoodInfoList = receiveMsg.getData();
        String[] resStr = str.split("-");
        String goodOrderId = resStr[2];
        List<Map<String,Object>> goodList = entryOrderService.queryGoodInfo(Integer.parseInt(goodOrderId));

        int flag = 0;

        // for循环判断到货和购货单是否一致
        for(InvoiceGoodInfo invoiceGoodInfo:invoiceGoodInfoList){
            for(Map<String,Object> goodMap:goodList){
                if(invoiceGoodInfo.getGoodId().equals(goodMap.get("goodId"))){
                    if(invoiceGoodInfo.getGoodCount() == goodMap.get("goodCount") && invoiceGoodInfo.getPrice() == goodMap.get("price")){
                        System.out.println("商品代码为："+invoiceGoodInfo.getGoodId()+"的商品核验通过.");

                    }
                    else {
                        this.checkPurchase(new MsgBean<String>(invoiceGoodInfo.getGoodId(),"false"),0);
                        flag++;
                    }
                }
            }
        }

        // 如果这批货物都核对无误，进行中心库房入库操作.入库后通知用户服务中心
        if(flag == 0){
            for(InvoiceGoodInfo invoiceGoodInfo:invoiceGoodInfoList){
                String orderId = entryOrderService.queryOrderIdByPurchase(invoiceGoodInfo.getGoodOrderId());
                Map<String,Object> entryMap = new HashMap<>();
                entryMap.put("entryOrderId",orderId);
                entryMap.put("purchaseOrderId",invoiceGoodInfo.getGoodOrderId());
                entryMap.put("warehouseId",1);
                entryMap.put("code",invoiceGoodInfo.getGoodId());
                entryMap.put("num",invoiceGoodInfo.getGoodCount());
                Long timeMillis = System.currentTimeMillis();
                Date inTime = new Date(timeMillis);
                entryMap.put("inTime",inTime);

                // 填写入库单和入库关系表
                entryOrderService.addEntryOrder(entryMap);
                eiRelationService.addEIRelation(entryMap);
                // 增加库存中中心仓库的商品数量
                inventoryService.increaseInventoryNum(entryMap);
                // 通知用户服务中心，中心库房已入库
                this.confirmPurchaseIn(new MsgBean(orderId,"中心库房已购货入库"),0);
            }
        }
    }

    // 根据货物调拨单生成分发单和出库单和分站库房入库单
    @StreamListener("create-distributeOrder")
    public void createDistributeOrder(@Payload MsgBean<GoodsTransferOrder> receiveMsg){
        try {
            System.out.println("*****"+receiveMsg+"*****");
            GoodsTransferOrder goodsTransferOrder = receiveMsg.getData();

            if(outOrderService.existOutOrder(goodsTransferOrder.getOrderId()) == 0){
                // 首先填写出库单
                Map<String,Object> outOrderMap = new HashMap<>();
                outOrderMap.put("outOrderId",goodsTransferOrder.getOrderId());
                outOrderMap.put("outTime",goodsTransferOrder.getOutboundTime());
                outOrderMap.put("outWarehouseId",goodsTransferOrder.getOutboundRoomId());
                outOrderService.addOutOrder(outOrderMap);
            }

            // 接下来填写分发单和分发关系表，并在库存商品表中更改商品数量
            Map<String,Object> map = new HashMap<>();
            map.put("distributionOrderId",goodsTransferOrder.getGoodsTransferOrderId());
            map.put("warehouseId",goodsTransferOrder.getInboundRoomId());// 入库库房编号
            // 分发时间比出库时间统一晚一天
            Date distributeDate = goodsTransferOrder.getOutboundTime();
            long distributeTime = distributeDate.getTime();
            distributeDate.setTime(distributeTime - 1000 * 60 * 60 * 24);
            map.put("distributeTime",distributeDate);
            map.put("company",goodsTransferOrder.getCompany());
            map.put("code",goodsTransferOrder.getCommodityId());
            map.put("num",goodsTransferOrder.getCommodityNum());
            map.put("outOrderId",goodsTransferOrder.getOrderId());
            map.put("outWarehouseId",goodsTransferOrder.getOutboundRoomId());
            distributionOrderService.addDistributionOrder(map);
            diRelationService.addDIRelation(map);
            // 如果分站库房中之前没有这种商品，就增加这种商品，如果有就直接改变数量
            if(inventoryService.existInventory(map) == 0){
                inventoryService.addInventory(map);
            }
            else {
                inventoryService.increaseInventoryNum(map);
            }
            // 中心库房减少商品数量
            inventoryService.decreaseInventoryNum(map);

            // 告诉客户服务中心，中心库房出库
            Map<String,Object> messageMap = new HashMap<>();
            messageMap.put("oid",goodsTransferOrder.getOrderId());
            messageMap.put("status", OrderStatus.Out_Of_Center_WareHouse);
            userFeignClient.changeOrderStatus(messageMap);

            List<Map<String,Object>> mapList = outOrderService.queryOutOrderById(goodsTransferOrder.getOrderId());
            this.checkPurchase1(mapList.get(0),0);
            // 接下来填写分站库房的入库单
            Map<String,Object> entryMap = new HashMap<>();
            entryMap.put("goodsTransferOrderId",goodsTransferOrder.getGoodsTransferOrderId());
            entryMap.put("entryOrderId",goodsTransferOrder.getOrderId());
            entryMap.put("warehouseId",goodsTransferOrder.getInboundRoomId());
            Date entryDate = goodsTransferOrder.getOutboundTime();
            long entryTime = entryDate.getTime();
            entryDate.setTime(entryTime + 1000 * 60 * 60 * 24);
            entryMap.put("inTime",entryDate);
            entryMap.put("code",goodsTransferOrder.getCommodityId());
            entryMap.put("num",goodsTransferOrder.getCommodityNum());
            System.out.println(entryOrderService.existEntryOrder(goodsTransferOrder.getOrderId()));
            if(entryOrderService.existEntryOrder(goodsTransferOrder.getOrderId()) == 0){
                entryOrderService.addEntryOrder(entryMap);
            }
            eiRelationService.addEIRelation(entryMap);
            // 告诉调度中心，中心库房已经运达分站库房
            this.confirmDistribute(new MsgBean(goodsTransferOrder.getOrderId(),"已经运达分站库房"),0);

            // 告诉客户服务中心，分站库房到货
            Map<String,Object> temp = new HashMap<>();
            temp.put("oid",goodsTransferOrder.getOrderId());
            temp.put("status", OrderStatus.Arrive_Distribution_Station);
            userFeignClient.changeOrderStatus(temp);


        }
        catch (Exception e){
            System.out.println(e.getMessage());
        }finally {
            return;
        }
    }

    @StreamListener("listen-packageSend")
    public void packageSend(@Payload MsgBean<List<String>> receiveMsg){
        System.out.println("*****"+receiveMsg+"*****");
        List<String> oidList = receiveMsg.getData();
        for(String oid:oidList){
            List<Map<String,Object>> shopList = dispatchFeignClient.findTransfer(oid).getData();
            for(Map<String,Object> map:shopList){
                Map<String,Object> shopMap = new HashMap<>();
                shopMap.put("code",map.get("commodityId"));
                shopMap.put("outWarehouseId",map.get("inboundRoomId"));
                shopMap.put("num",map.get("commodityNum"));
                inventoryService.decreaseInventoryNum(shopMap);
            }

            // 修改订单状态
            Map<String,Object> orderTemp = new HashMap<>();
            orderTemp.put("oid",oid);
            orderTemp.put("status", OrderStatus.Picked_By_Deliveryman);
            userFeignClient.changeOrderStatus(orderTemp);
        }
    }
}
